home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_1.3 / Read-Me1.3 / Printer1.3 / Driver.Examples / src / xerox_4020 / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-01  |  9.6 KB  |  354 lines

  1. /*
  2.     Xerox-4020 driver.
  3.     David Berezowski - October/87.
  4. */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/nodes.h>
  8. #include <exec/lists.h>
  9. #include <exec/memory.h>
  10. #include "../printer/printer.h"
  11. #include "../printer/prtbase.h"
  12.  
  13. #define NUMSTARTCMD    7    /* # of cmd bytes before binary data */
  14. #define NUMENDCMD    0    /* # of cmd bytes after binary data */
  15. #define NUMTOTALCMD     (NUMSTARTCMD + NUMENDCMD)    /* total of above */
  16. #define NUMLFCMD    9    /* # of cmd bytes for linefeed */
  17. #define MAXCOLORBUFS    16    /* max # of color buffers */
  18.  
  19. #define RLEMAX        136
  20. #define RLENUMSTARTCMD    3    /* # of cmd bytes before binary data */
  21. #define RLENUMENDCMD    1    /* # of cmd bytes after binary data */
  22. #define RLENUMTOTALCMD     (RLENUMSTARTCMD + RLENUMENDCMD)    /* total of above */
  23. #define RLESAFETY    10    /* extra room for overwrites */
  24.  
  25. #define PMODE        15    /* index into StartBuf for print mode */
  26. #define STARTLEN    16    /* length of start buffer */
  27.  
  28. extern UBYTE MargBuf[];
  29.  
  30. Render(ct, x, y, status)
  31. long ct, x, y, status;
  32. {
  33.     extern void *AllocMem(), FreeMem();
  34.     extern struct PrinterData *PD;
  35.     extern struct PrinterExtendedData *PED;
  36.  
  37.     static UWORD RowSize, ColorSize, BufSize, TotalBufSize, dataoffset;
  38.     static UWORD colors[MAXCOLORBUFS]; /* color indexes */
  39.     static UWORD color_order[] =
  40.         {0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15};
  41.     static UWORD huns, tens, ones; /* used to program buffer size */
  42.     static UWORD NumColorBufs; /* actually # of color buffers */
  43.     /*
  44.         00-02    \033F0        set 10 cpi
  45.         03-07    \033l05\r    set left margin to .5 inches
  46.         09-12    \033r95\r    set right margin to 9.5 inches
  47.         13-15    \033we        select standard (e) or
  48.                     enhanced (f) graphics mode.
  49.     */
  50.     static UBYTE stdmode, StartBuf[STARTLEN] =
  51.         "\033F0\033l05\r\033r95\r\033we";
  52.     UBYTE *ptr, *ptrstart, *ptr2, *ptr2start;
  53.     int i, err;
  54.  
  55.     static UWORD RLEBufSize, rledataoffset;
  56.     static UBYTE *RLEBuf;
  57.     UBYTE *rleptrstart, *rleptr, *rleptrmark, rledata;
  58.     int rlesize, rlecount, j;
  59.  
  60.     switch(status) {
  61.         case 0 : /* Master Initialization */
  62.             /*
  63.                 ct    - pointer to IODRPReq structure.
  64.                 x    - width of printed picture in pixels.
  65.                 y    - height of printed picture in pixels.
  66.             */
  67.             /* calc # of bytes of row data */
  68.             RowSize = (x + 7) / 8;
  69.             /* size of each color buf */
  70.             ColorSize = RowSize + NUMTOTALCMD;
  71.             huns = RowSize / 100;
  72.             tens = (RowSize - huns * 100) / 10;
  73.             ones = RowSize % 10;
  74.             if (PD->pd_Preferences.PrintShade == SHADE_COLOR) {
  75.                 NumColorBufs = MAXCOLORBUFS;
  76.             }
  77.             else {
  78.                 NumColorBufs = 4;
  79.             }
  80.             BufSize = ColorSize * NumColorBufs + NUMLFCMD;
  81.             TotalBufSize = BufSize * 2;
  82.             RLEBufSize = BufSize + RLESAFETY;
  83.             TotalBufSize += RLEBufSize * 2;
  84.             /*
  85.                 My color order:        B, Y, M, C
  86.                 Xerox's color order:    B, M, Y, C
  87.             */
  88.             for (i=0; i<NumColorBufs; i++) {
  89.                 colors[color_order[i]] = ColorSize * i;
  90.             }
  91.             PD->pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
  92.             if (PD->pd_PrintBuf == NULL) {
  93.                 err = PDERR_BUFFERMEMORY; /* no mem */
  94.             }
  95.             else {
  96.                 dataoffset = NUMSTARTCMD;
  97.                 err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  98.                 RLEBuf = &PD->pd_PrintBuf[BufSize * 2];
  99.                 rledataoffset = RLENUMSTARTCMD;
  100.             }
  101.             break;
  102.  
  103.         case 1 : /* Scale, Dither and Render */
  104.             /*
  105.                 ct    - pointer to PrtInfo structure.
  106.                 x    - 0.
  107.                 y    - row # (0 to Height - 1).
  108.             */
  109.             Transfer(ct, y, &PD->pd_PrintBuf[dataoffset], colors);
  110.             err = PDERR_NOERR; /* all ok */
  111.             break;
  112.  
  113.         case 2 : /* Dump Buffer to Printer */
  114.             /*
  115.                 ct    - 0.
  116.                 x    - 0.
  117.                 y    - # of rows sent (1 to NumRows).
  118.             */
  119.             /* Run-Length Encode (rle) the data */
  120.             rleptrstart = rleptr =
  121.                 &RLEBuf[rledataoffset - RLENUMSTARTCMD];
  122.             /* ptr to data */
  123.             ptrstart = &PD->pd_PrintBuf[dataoffset];
  124.             for (ct=0; ct<NumColorBufs;
  125.                 ct++, ptrstart += ColorSize) {
  126.                 /* save start posn for this color */
  127.                 rleptrmark = rleptr;
  128.                 *rleptr++ = 27; /* rle start cmd */
  129.                 *rleptr++ = 'h';
  130.                 *rleptr++ = ct | '0'; /* color code */
  131.                 ptr = ptrstart; /* get ptr to bytes to rle */
  132.                 j = RowSize - 1; /* # of bytes left to rle */
  133.                 do {
  134.                     /* first do repeating bytes */
  135.                     /* get goal (repeating) byte */
  136.                     rledata = *ptr++;
  137.                     /* this many repetitions left to go*/
  138.                     i = RLEMAX - 1;
  139.                     /* while repeating and not too many
  140.                         and more to do */
  141.                     while (*ptr == rledata && i > 0 &&
  142.                         j > 0) {
  143.                         i--; /* one more rle byte */
  144.                         /* advance ptr to next byte */
  145.                         ptr++;
  146.                         /* one less byte to look at */
  147.                         j--;
  148.                     }
  149.                     /* calc repeating byte count */
  150.                     if ((rlecount = RLEMAX - i) == 1) {
  151.                         /* if only 1 then no repeat */
  152.                         rlecount = 0;
  153.                     }
  154.                     else {
  155.                         /* dont forget the goal byte */
  156.                         j--;
  157.                     }
  158.                     /* if there was repeat data */
  159.                     if (rlecount != 0) {
  160.                         /* save repeat count */
  161.                         *rleptr++ = rlecount;
  162.                         /* save repeat byte */
  163.                         *rleptr++ = rledata;
  164.                         /* get non-repeat goal byte */
  165.                         rledata = *ptr++;
  166.                     }
  167.                     /* now do non-repeating data */
  168.                     /* no non-repeating bytes yet */
  169.                     rlecount = 0;
  170.                     if (*ptr != rledata && j >= 0) {
  171.                         /* non-repeat data follows */
  172.                         *rleptr++ = 0x00;
  173.                     }
  174.                     /* while non-repeating and more to do */
  175.                     while (*ptr != rledata && j >= 0) {
  176.                         /* save byte */
  177.                         *rleptr++ = rledata;
  178.                         /* if byte same as terminator */
  179.                         if (rledata == 0xfe) {
  180.                             /* save byte (again) */
  181.                             *rleptr++ = rledata;
  182.                         }
  183.                         /* one more non-repeat byte */
  184.                         rlecount++;
  185.                         /* get goal byte */
  186.                         rledata = *ptr++;
  187.                         /* one less byte to look at */
  188.                         j--;
  189.                     }
  190.                     if (rlecount != 0) {
  191.                         /* end of non-repeating bytes */
  192.                         *rleptr++ = 0xfe;
  193.                     }
  194.                     if (j > 0) { /* if more data to do */
  195.                         /* set ptr back to start
  196.                             of repeat bytes */
  197.                         ptr--;
  198.                     }
  199.                     if (rleptr - rleptrstart > BufSize) {
  200.                         /* abort: too many rle bytes */
  201.                         break;
  202.                     }
  203.                 } while (j > 0); /* while more bytes to rle */
  204.  
  205.                 /* if didnt abort && no non-repeating data */
  206.                 if (j < 1 && rlecount == 0) {
  207.                     /* check for trailing white space */
  208.                     /* line ends in trailing 0 */
  209.                     if (*(rleptr - 1) == 0x00) {
  210.                         /* ptr back to repeat count */
  211.                         rleptr -= 2;
  212.                     }
  213.                 }
  214.                 /* if line is just the cmd bytes */
  215.                 /* line null */
  216.                 if (rleptr - rleptrmark == RLENUMSTARTCMD) {
  217.                     /* reset ptr to start */
  218.                     rleptr = rleptrmark;
  219.                 }
  220.                 else {
  221.                     *rleptr++ = 0xff; /* end of rle line */
  222.                 }
  223.             }
  224.             i = rleptr - rleptrstart; /* calc size of rlebuf */
  225.             /* if rle data is more send non-rle data */
  226.             if (i > BufSize) {
  227.                 ptrstart = &PD->pd_PrintBuf[dataoffset -
  228.                     NUMSTARTCMD];
  229.                 ptr = ptrstart + BufSize - NUMLFCMD;
  230.                 /* if standard print mode and any black
  231.                     in this micro-line */
  232.                 if (stdmode && *(ptrstart + 2) < '4') {
  233.                     *ptr++ = 27;
  234.                     *ptr++ = 'k';
  235.                     *ptr++ = '0';    /* cr */
  236.                     *ptr++ = 27;
  237.                     *ptr++ = 'w';
  238.                     *ptr++ = 'B';    /* repeat black */
  239.                 }
  240.                 *ptr++ = 27;
  241.                 *ptr++ = 'k';
  242.                 *ptr++ = '1';        /* cr/lf */
  243.                 err = (*(PD->pd_PWrite))
  244.                     (ptrstart, ptr - ptrstart);
  245.             }
  246.             else { /* send rle data */
  247.                 /* if any black in this micro-line */
  248.                 if (rleptr - rleptrstart > 0 &&
  249.                     *(rleptrstart + 2) < '4') {
  250.                     *rleptr++ = 27;
  251.                     *rleptr++ = 'k';
  252.                     *rleptr++ = '0'; /* cr */
  253.                     *rleptr++ = 27;
  254.                     *rleptr++ = 'w';
  255.                     *rleptr++ = 'B'; /* repeat black */
  256.                 }
  257.                 *rleptr++ = 27;
  258.                 *rleptr++ = 'k';
  259.                 *rleptr++ = '1';    /* cr/lf */
  260.                 i = rleptr - rleptrstart; /* size of rlebuf */
  261.                 err = (*(PD->pd_PWrite))(rleptrstart, i);
  262.             }
  263.             if (err == PDERR_NOERR) {
  264.                 dataoffset = (dataoffset == NUMSTARTCMD ?
  265.                     BufSize : 0) + NUMSTARTCMD;
  266.                 rledataoffset = (rledataoffset ==
  267.                     RLENUMSTARTCMD ? RLEBufSize : 0) +
  268.                     RLENUMSTARTCMD;
  269.             }
  270.             break;
  271.  
  272.         case 3 : /* Clear and Init Buffer */
  273.             /*
  274.                 ct    - 0.
  275.                 x    - 0.
  276.                 y    - 0.
  277.             */
  278.             ptr = &PD->pd_PrintBuf[dataoffset];
  279.             i = BufSize - NUMTOTALCMD - NUMLFCMD;
  280.             do {
  281.                 *ptr++ = 0;
  282.             } while (--i);
  283.             for (ct=0; ct<NumColorBufs; ct++) {
  284.                 ptr = &PD->pd_PrintBuf[dataoffset -
  285.                     NUMSTARTCMD + ct * ColorSize];
  286.                 *ptr++ = 27;
  287.                 *ptr++ = 'g';
  288.                 *ptr++ = ct + '0';    /* color */
  289.                 *ptr++ = huns | '0';
  290.                 *ptr++ = tens | '0';
  291.                 *ptr++ = ones | '0';    /* printout width */
  292.                 *ptr = ',';        /* terminator */
  293.             }
  294.             err = PDERR_NOERR; /* all ok */
  295.             break;
  296.  
  297.         case 4 : /* Close Down */
  298.             /*
  299.                 ct    - error code.
  300.                 x    - io_Special flag from IODRPReq.
  301.                 y    - 0.
  302.             */
  303.             /* if user did not cancel print */
  304.             if (ct != PDERR_CANCEL) {
  305.                 /* restore preferences pitch and margins */
  306.                 i = CalcMarg(PD->pd_Preferences.PrintLeftMargin
  307.                     , PD->pd_Preferences.PrintRightMargin);
  308.                 err = (*(PD->pd_PWrite))(MargBuf, i);
  309.             }
  310.             /* wait for both buffers to empty */
  311.             (*(PD->pd_PBothReady))();
  312.             if (PD->pd_PrintBuf != NULL) {
  313.                 FreeMem(PD->pd_PrintBuf, TotalBufSize);
  314.             }
  315.             err = PDERR_NOERR; /* all ok */
  316.             break;
  317.  
  318.         case 5 : /* Pre-Master Initialization */
  319.             /*
  320.                 ct    - 0 or pointer to IODRPReq structure.
  321.                 x    - io_Special flag from IODRPReq.
  322.                 y    - 0.
  323.             */
  324.             StartBuf[PMODE - 1] = 'w';
  325.             if ((x & SPECIAL_DENSITYMASK) < SPECIAL_DENSITY2) {
  326.                 /* standard graphics mode */
  327.                 StartBuf[PMODE] = 'e';
  328.                 stdmode = 1;
  329.             }
  330.             else {
  331.                 /* enhanced graphics mode */
  332.                 StartBuf[PMODE] = 'f';
  333.                 stdmode = 0;
  334.             }
  335.             PED->ped_MaxColumns = PD->pd_Preferences.PaperSize ==
  336.                 W_TRACTOR ? 90 : 80;
  337.             /* def is 80 chars (8.0 in.),
  338.                 W_TRACTOR is 90 chars (9.0 in.) */
  339.             PED->ped_MaxXDots = (PED->ped_XDotsInch *
  340.                 PED->ped_MaxColumns) / 10;
  341.             /*
  342.             The manual says that the printer has 1088 dots BUT I
  343.             could never get more than 1080 out of it.  This kludge
  344.             is here as '121 * 90 / 10 = 1089' which is > 1080.
  345.             */
  346.             if (PED->ped_MaxXDots > 1080) {
  347.                  PED->ped_MaxXDots = 1080;
  348.             }
  349.             err = PDERR_NOERR; /* all ok */
  350.             break;
  351.     }
  352.     return(err);
  353. }
  354.